/**
 * @filename:SupplimentServiceImpl Dec 20, 2023
 * @project Wonder Vue Admin Api  1.1.0
 * Copyright(c) 2022 Wonder Co. Ltd. 
 * All right reserved. 
 */
package com.wonder.app.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.vtuzx.core.VtuzxException;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.*;
import com.wonder.app.service.InventoryService;
import com.wonder.app.service.SupplimentDetailService;
import com.wonder.app.service.SupplimentService;
import com.wonder.app.request.SupplimentRequest;
import com.wonder.bean.kingdee.xqc.BillMaterial;
import com.wonder.common.exception.CustomException;
import com.wonder.common.utils.DateUtils;
import com.wonder.common.utils.StringUtils;
import com.wonder.common.utils.MessageUtils;
import com.wonder.common.common.AjaxResult;

import java.util.*;

import com.wonder.constant.BillEvent;
import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

/**   
 * @Description:TODO(生产补料服务实现)
 *
 * @version: 1.1.0
 * @author: Wonder
 * 
 */
@Service
public class SupplimentServiceImpl  extends ServiceImpl<SupplimentDao, Suppliment> implements SupplimentService  {
	/**
	 * Logger
	 */
	private static final Logger _logger = LoggerFactory.getLogger(SupplimentServiceImpl.class);

	@Autowired
	private SupplimentDao supplimentDao;

	@Autowired
	private SupplimentDetailDao supplimentDetailDao;

	@Autowired
	private InventoryService inventoryService;

	@Autowired
	private SupplimentService supplimentService;

	@Autowired
	private SupplimentDetailService supplimentDetailService;


	@Autowired
	private ProppbomlistDao proppbomlistDao;

	@Autowired
	private InventoryDao inventoryDao;

	@Autowired
	private ProppbomDao proppbomDao;

	@Autowired
	private ProorderDao proorderDao;

    /**
     * 验证生产补料信息
     * 
     * @param suppliment
     * @param type
     * @return String
     */
    @Override
    public String validate(Suppliment suppliment,String type){
    
    
       return "";
    }
    
    
    /**
	 * Description:生产补料分页返回
	 * @param request //检索条件
	 * @param page //分页参数
	 * @return IPage<Suppliment>   //分页记录
	 */
	@Override 
	public IPage<Suppliment> selectList(SupplimentRequest request, Page<Suppliment> page){
		LambdaQueryWrapper<Suppliment> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		String billNo = request.getBillNo();
		String taskBillNo = request.getTaskBillNo();

	    if (!VtuzxUtil.isEmpty(billNo)){
	    	lambdaQueryWrapper.like(Suppliment::getBillNo,billNo);
		}
		if (!VtuzxUtil.isEmpty(taskBillNo)){
			lambdaQueryWrapper.like(Suppliment::getTaskBillNo,taskBillNo);
		}

	    if (null != request.getId()) {
	       lambdaQueryWrapper.eq(Suppliment::getId, request.getId());
	      }

		if (request.getCreateTime() != null){
			Date[] createTime=request.getCreateTime();
			if(createTime.length>0)
				lambdaQueryWrapper.ge(Suppliment::getCreateTime, createTime[0]);
			if(createTime.length==2)
				lambdaQueryWrapper.le(Suppliment::getCreateTime, DateUtils.dateToStr(createTime[1],"yyyy-MM-dd")+ " 23:59:59");

		}

		lambdaQueryWrapper.orderByDesc(Suppliment::getId);	
		Page<Suppliment> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
		return selectPage;
    }

	@Override
	public VtuzxMap getSupplimentDetail(Long id) {
		VtuzxMap data = new VtuzxMap();
		Suppliment suppliment = supplimentDao.selectOne(new QueryWrapper<Suppliment>().eq("id",id));
		List<SupplimentDetail> supplimentDetails = supplimentDetailDao.selectList(new QueryWrapper<SupplimentDetail>().eq("entryId",id));
		data.append("header",suppliment)
				.append("dataList",supplimentDetails);
		return data;
	}

	@Override
	public boolean unAuditSuppliment(Long user_id, String userName, Long id) {
		Suppliment suppliment = supplimentDao.selectById(id);
		suppliment.setUpdateTime(new DateTime());
		suppliment.setUpdateUserName(userName);
		suppliment.setStatus("unAudit");
		String billNo = suppliment.getBillNo();

		//反审需要把扣减掉的库存增加
		List<SupplimentDetail> detailList = supplimentDetailDao.selectList(new QueryWrapper<SupplimentDetail>()
				.eq("entryId", id));

		List<BillMaterial> dataList = new ArrayList<>();//需要增加的库存
		for (SupplimentDetail data : detailList) {
			BillMaterial material = new BillMaterial();
			material.setMaterialNo(data.getMaterialNo());
			material.setMaterialName(data.getMaterialName());
			material.setMaterialModel(data.getSpecification());
			material.setCount(data.getCount());
			material.setStockNo(data.getStockNo());
			material.setBatchNo(data.getFlot());
			material.setUnit(data.getUnit());
			material.setProduceDate(data.getProduceDate());
			material.setExpiryDate(data.getExpiryDate());
			material.setProduce(data.getIsProduce());
			material.setFlot(data.getIsFlot());
			dataList.add(material);
		}
		try {
			Map<String, Object> stringObjectMap = inventoryService.addInventory(user_id, userName, BillEvent.Unaudit, BillType.SCBL, billNo, dataList);
			if (!(Boolean) stringObjectMap.get("status")){
				return false;
			}
		} catch (Exception e){
			_logger.info(e.getMessage());
		}

		boolean isSuccess = supplimentService.updateById(suppliment);

		return isSuccess;
	}

	@Override
	public boolean auditSuppliment(Long user_id, String userName, Long id) {
		Suppliment suppliment = supplimentDao.selectById(id);
		suppliment.setUpdateTime(new DateTime());
		suppliment.setUpdateUserName(userName);
		suppliment.setStatus("audit");
		suppliment.setAuditTime(new DateTime());
		suppliment.setAuditUserName(userName);
		String billNo = suppliment.getBillNo();
		//审核订单需要扣减库存
		List<SupplimentDetail> detailList = supplimentDetailDao.selectList(new QueryWrapper<SupplimentDetail>()
				.eq("entryId", id));

		List<BillMaterial> dataList = new ArrayList<>();//需要扣减的库存
		for (SupplimentDetail data : detailList) {
			BillMaterial material = new BillMaterial();
			material.setMaterialNo(data.getMaterialNo());
			material.setMaterialName(data.getMaterialName());
			material.setMaterialModel(data.getSpecification());
			material.setCount(data.getCount());
			material.setStockNo(data.getStockNo());
			material.setBatchNo(data.getFlot());
			material.setUnit(data.getUnit());
			material.setProduceDate(data.getProduceDate());
			material.setExpiryDate(data.getExpiryDate());
			material.setProduce(data.getIsProduce());
			material.setFlot(data.getIsFlot());
			dataList.add(material);
		}
		try {
			Map<String, Object> stringObjectMap = inventoryService.reduceInventory(user_id, userName, BillEvent.Audit, BillType.SCLL, billNo, dataList);
			if (!(Boolean) stringObjectMap.get("status")){
				return false;
			}

		} catch (Exception e){
			_logger.info(e.getMessage());
		}

		boolean isSuccess = supplimentService.updateById(suppliment);

		return isSuccess;
	}

	@Override
	public VtuzxMap getBomList(String taskBillNo) {
		VtuzxMap data = new VtuzxMap();
		List<Proppbomlist> bomList = proppbomlistDao.selectList(new QueryWrapper<Proppbomlist>().eq("taskBillNo", taskBillNo));


		return data.append("dataList",bomList);
	}

	@Override
	public VtuzxMap changeSuppliment(Long user_id, String userName, Map<String, Object> header, List<Map<String, Object>> dataList) {
		Long id = Long.parseLong(header.get("id").toString());
		String taskBillNo = header.get("taskBillNo").toString();

		//1.删除之前的领料详情信息
		int deleteCount = supplimentDetailDao.delete(new QueryWrapper<SupplimentDetail>().eq("entryId", id));
		//添加新的领料信息
		List<SupplimentDetail> detailList = new ArrayList<>();
		for (Map<String, Object> map : dataList) {
			SupplimentDetail detail = new SupplimentDetail();
			detail.setMaterialNo(map.get("materialNo").toString());
			detail.setMaterialName(map.get("materialName").toString());
			detail.setSpecification(map.get("specification").toString());
			detail.setCount(Double.parseDouble(map.get("stdQty").toString()));
			detail.setUnit(map.get("unit").toString());
			detail.setTaskBillNo(taskBillNo);
			detail.setEntryId(id);
			detail.setPpBomNo(map.get("billNo").toString());
			detail.setIsFlot((Boolean) map.get("isFlot"));
			detail.setIsProduce((Boolean) map.get("isProduce"));
			detail.setCreateTime(new DateTime());
			detail.setCreateUserId(user_id);
			detail.setCreateUserName(userName);
			detail.setUpdateTime(new DateTime());
			detail.setUpdateUserName(userName);
			detailList.add(detail);
		}
		boolean isSuccess = supplimentDetailService.saveBatch(detailList);
		return new VtuzxMap("res",isSuccess).append("dataList",detailList);
	}

	@Override
	public boolean saveSuppliment(String userName, Map<String,Object> header,List<Map<String, Object>> dataList) {
		List<SupplimentDetail> detailList = new ArrayList<>();
		double sumCount = 0;
		for (Map<String,Object> map : dataList) {
			SupplimentDetail detail = new SupplimentDetail();
			detail.setId(VtuzxUtil.getLong(map,"id"));
			detail.setBillNo(VtuzxUtil.getString(map,"billNo"));
			detail.setMaterialNo(VtuzxUtil.getString(map,"materialNo"));
			detail.setMaterialName(VtuzxUtil.getString(map,"materialName"));
			detail.setSpecification(VtuzxUtil.getString(map,"specification"));
			detail.setFlot(VtuzxUtil.getString(map,"flot"));
			detail.setProduceDate(VtuzxUtil.parseDate(VtuzxUtil.getString(map,"produceDate")));
			detail.setExpiryDate(VtuzxUtil.parseDate(VtuzxUtil.getString(map,"expiryDate")));
			detail.setUnit(VtuzxUtil.getString(map,"unit"));
			detail.setStockNo(VtuzxUtil.getString(map,"stockNo"));
			detail.setWorkShop(VtuzxUtil.getString(map,"workShop"));
			detail.setTaskBillNo(VtuzxUtil.getString(map,"taskBillNo"));
			detail.setPpBomNo(VtuzxUtil.getString(map,"pbomNo"));
			detail.setCount(VtuzxUtil.getDouble(map,"count"));
			detail.setIsProduce(VtuzxUtil.getBoolean(map,"isProduce"));
			detail.setIsFlot(VtuzxUtil.getBoolean(map,"isFlot"));
			detail.setUpdateUserName(userName);
			detail.setUpdateTime(new DateTime());
			detailList.add(detail);
			sumCount += VtuzxUtil.getDouble(map,"count");
		}

		//修改外层的数量
		Long id = Long.parseLong(header.get("id").toString());
		Suppliment suppliment = supplimentDao.selectById(id);
		suppliment.setCount(sumCount);
		suppliment.setStatus("save");

		boolean res = supplimentDetailService.saveOrUpdateBatch(detailList);
		boolean suppRes = supplimentService.updateById(suppliment);
		return res && suppRes;
	}

	@Override
	public Boolean saveSupplimentPad(JSONObject map) throws Exception {
		String taskBillNo = map.getStr("taskBillNo");
		String userName = map.getStr("userName");
		Long userId = map.getLong("userId");
		JSONArray jsonArray = map.getJSONArray("material");//物料信息
		List<SupplimentDetail> detailList = new ArrayList<>();
		//从生产订单查询用料清单号
		Proorder proorder = proorderDao.selectOne(new QueryWrapper<Proorder>().eq("billNo", taskBillNo));
		String pbomNo = proorder.getPbomNo();//用料清单号

		String billNo = IXqcConst.createBillNo(BillType.SCBL);


		double sumCount = 0;//外层表总数
		for (int i = 0;i < jsonArray.size(); i++ ){
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			String materialNo = jsonObject.getStr("materialNo");
			String materialName = jsonObject.getStr("materialName");
			String specification = jsonObject.getStr("specification");
			String stockNo = jsonObject.getStr("stockNo");
			String batchNo = jsonObject.getStr("batchNo");
			String unit = jsonObject.getStr("unit");
			double count = jsonObject.getDouble("count");
			sumCount += count;
			//先查询库存是否存在所需要的品以及数量是否够
			LambdaQueryWrapper<Inventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
			lambdaQueryWrapper.eq(Inventory::getFMaterialNumber,materialNo)
					.eq(Inventory::getFStockNumber,stockNo);
			if(!VtuzxUtil.isEmpty(batchNo)){
				lambdaQueryWrapper.eq(Inventory::getFlot,batchNo);
			}
			Inventory inventory = inventoryDao.selectOne(lambdaQueryWrapper);
			if (null == inventory){
				throw new Exception(String.format("货品:%s不在库",materialNo));
			}
			Double fqty = inventory.getFqty();
			if (fqty <= 0){
				throw new Exception(String.format("货品:%s库存不足",materialNo));
			}
			//先创建补料内层表数据
			SupplimentDetail supplimentDetail = new SupplimentDetail();
			supplimentDetail.setMaterialNo(materialNo);
			supplimentDetail.setMaterialName(materialName);
			supplimentDetail.setSpecification(specification);
			if (!VtuzxUtil.isEmpty(batchNo)){
				supplimentDetail.setFlot(batchNo);
				supplimentDetail.setIsFlot(true);
			}
			supplimentDetail.setUnit(unit);
			supplimentDetail.setStockNo(stockNo);
			supplimentDetail.setTaskBillNo(taskBillNo);
			supplimentDetail.setPpBomNo(pbomNo);
			supplimentDetail.setCreateUserName(userName);
			supplimentDetail.setCreateUserId(userId);
			supplimentDetail.setCount(count);
			supplimentDetail.setBillNo(billNo);
			detailList.add(supplimentDetail);
		}
		//保存外层表数据
		Suppliment suppliment = new Suppliment();
		suppliment.setBillNo(billNo);
		suppliment.setStatus("unAudit");
		suppliment.setPicker(userName);
		suppliment.setTaskBillNo(taskBillNo);
		suppliment.setPpBomNo(pbomNo);
		suppliment.setCreateUserName(userName);
		suppliment.setCreateUserId(userId);
		suppliment.setCount(sumCount);
		boolean save = supplimentService.save(suppliment);
		Long id = suppliment.getId();
		//保存内层表数据
		for (SupplimentDetail supplimentDetail : detailList){
			supplimentDetail.setEntryId(id);
		}
		boolean detailRes = supplimentDetailService.saveOrUpdateBatch(detailList);
		//审核补料单
		try {
			auditSuppliment(userId,userName,id);
		} catch (Exception e){
			throw new CustomException(e.getMessage());
		}

		return save && detailRes;
	}


}